using System;
using System.Linq;
using System.Collections.Generic;
using System.Reflection;
using System.Diagnostics;

namespace SubSpec.Expression
{
	public static class SpecificationExpression
	{
		public static SpecificationExpression<TFixture> Begin<TFixture>(Func<TFixture> context)
		{
			const int framesToSkip = 1; // this
			var source = new StackFrame(framesToSkip);

			return new SpecificationExpression<TFixture>(context, source);
		}
	}

    public class SpecificationExpression<TFixture>
	{
		private TFixture _context;

        internal SpecificationExpression( Func<TFixture> contextSetup, StackFrame source )
        {
            if (contextSetup == null)
                throw new ArgumentNullException( "context", "context is null." );
            if (source == null)
                throw new ArgumentNullException( "source", "source is null." );

            source.GetMethod().Name.Context( () => _context = contextSetup() );
        }

		public SpecificationExpression<TFixture> Where(Action<TFixture> predicate)
		{
			SpecificationContext.Do("", () => predicate(_context));

			return this;
		}

		public SpecificationExpression<TFixture> Select(Func<TFixture, Observations> selector)
		{
			SpecificationContext.SetObservations(() => selector(_context).Select(x => new SpecificationPrimitive<Action>("", x)));
			
			return this;
		}
	}
}